--- redirect_from: - "/05/subsection/02/demo-3d" interact_link: content/05/subsection/02/Demo_3D.ipynb kernel_name: python3 kernel_path: content/05/subsection/02 has_widgets: false title: |- 3D figure pagenum: 9 prev_page: url: /05/subsection/01/PlotlyDemo.html next_page: url: suffix: .ipynb search: create plotly animation uses sliders navigate through cross sections bsub sub mapped brain comment: "***PROGRAMMATICALLY GENERATED, DO NOT EDIT. SEE ORIGINAL FILES IN /content***" ---
3D figure

How to create a Plotly animation that uses sliders to navigate through cross-sections of a B1 mapped brain

import os
import numpy as np
import plotly.graph_objects as go
from plotly.offline import download_plotlyjs, init_notebook_mode,  iplot, plot
from IPython.core.display import display, HTML
import scipy.io as sio

init_notebook_mode(connected=True)
config={'showLink': False, 'displayModeBar': False}

# Comment out if locally 
os.chdir("/home/jovyan/content/05/subsection/02")

# Load data
matrix = sio.loadmat(file_name = "newmap.mat", matlab_compatible = True)
newmap = matrix['vect']

# Create list for 32 slices
data = []
for i in range(32):
    z_current = np.rot90(newmap[:,i,:])
    data_c = go.Heatmap(z = z_current,
                        showscale = True,
                        colorscale = 'Greens', 
                        visible = False,
                        xtype = "scaled", 
                        ytype = "scaled")
    data.append(data_c)

# Get rows and columns
_,r, c = newmap.shape
volume = newmap    

# Define frames
nb_frames = 32

fig = go.Figure(frames=[go.Frame(data=go.Surface(
    z=(31 - k * 1) * np.ones((r, c)),
    surfacecolor=np.flipud(volume[31 - k]),
    cmin=0, cmax=80
    ),
    name=str(k) 
    )
    for k in range(nb_frames)])

# Add data to be displayed before animation starts
fig.add_trace(go.Surface(
    z=41 * np.ones((r, c)),
    surfacecolor=np.flipud(volume[31]),
    colorscale='Viridis',
    cmin=0, cmax=80,
    colorbar=dict(thickness=20, ticklen=3, title = dict(text = "FA [°]"))
    ))


def frame_args(duration):
    return {
            "frame": {"duration": duration},
            "mode": "immediate",
            "fromcurrent": True,
            "transition": {"duration": duration, "easing": "linear"},
        }

# create sliders
sliders = [
            {
                "pad": {"b": 10, "t": 60},
                "len": 0.9,
                "x": 0.1,
                "y": 0,
                "currentvalue": {'prefix':"Current slice is: <b>"},
                "steps": [
                    {
                        "args": [[f.name], frame_args(0)],
                        "label": str(abs(32 - k)),
                        "method": "animate",
                    }
                    for k, f in enumerate(fig.frames)
                ],
            }
        ]

# Layout
fig.update_layout(
         title='Slices from B1+ mapping data',
         width=550,
         height=660,
         scene=dict(
                    zaxis=dict(range=[0, 32], autorange=False),
                    aspectratio=dict(x=0.8, y=0.8, z=0.8),
                    ),
         updatemenus = [
            {
                "buttons": [
                    {
                        "args": [None, frame_args(50)],
                        "label": "&#9654;", # play symbol
                        "method": "animate",
                    },
                    {
                        "args": [[None], frame_args(0)],
                        "label": "&#9724;", # pause symbol
                        "method": "animate",
                    },
                ],
                "direction": "left",
                "pad": {"r": 10, "t": 70},
                "type": "buttons",
                "x": 0.1,
                "y": 0,
            }
         ],
         sliders=sliders
)

# Display figure
plot(fig, filename = 'fig_3d.html', config = config)
display(HTML('fig_3d.html'))